#ifndef INSTANCE_H
#define INSTANCE_H


#include "character.h"
#include "player.h"
#include "gameprocess.h"
#include "cardmanage.h"
#include "MsgModPC.h"
#include "macros.h"

CBasicGameCard *GetBasicCard();

class CGameInstance : public CMsgModPC
{
public:
	typedef struct {
		CUser::T_UserUniqueID	 id;
		int	playerid;
	} T_UserInfo;
	bool GameStart;

	typedef string T_InstanceID;
	typedef map<T_ModuleDescriptor, T_UserInfo> T_UserRoomMap;
	T_InstanceID ID;
	CPlayerManage Player;
	CCardManage Card;
	CGameProcess Game;

	T_ModuleDescriptor Host;
	T_UserRoomMap Users;
	//void StartInstance();
	void StartGame()
	{
		CBasicGameCard *bgc = GetBasicCard();
		Card.Init(bgc->BasicCharacters, 
			bgc->BasicNavigations,
			bgc->BasicItems,
			bgc->BasicPosition);
		Game.Init(&Card, &Player);
	}

public:
	virtual void MOnRecvMsg(unsigned int type, T_LParameter lp, const DataFlow &data)
	{
		bool ishost = 0;
		string retmsg;
		int ret;
		T_ModuleDescriptor md;
		T_UserInfo user;
		user.playerid = -1;
		switch (type)
		{
		case MSG_PLAYER_HOST_JOIN:
			ishost = 1;
		case MSG_PLAYER_JOIN:
			md = lp;
			user.id = data.GetData();
			if (ishost) Host = md;
			if ( MAP_NOT_CONTAIN(Users, md) )
			{
				ret = Player.AllocateFreePlayer(md);

				if (ret != -1)
				{
					Users[md] = user;
					POST_MSG_TO(md, MSG_PLAYER_JOIN_ACCEPT, GetMD(), ret );
				}
				else
					POST_MSG_TO(md, MSG_PLAYER_JOIN_DENY, GetMD(), null );
			}
			break;
		case MSG_GAME_START:
			md = lp;
			user.id = data.GetData();
			if ( (!GameStart) && (md == Host) )
			{
				if (Player.PlayerNumber < 2)
				{
					retmsg = "Not enough player";
					POST_MSG_TO(md, MSG_GAME_START_DENY, GetMD(), retmsg );
					break;
				}
				POST_MSG_TO(md, MSG_GAME_START_ACCEPT, GetMD(), null );
				GameStart = 1;
				StartGame();
			}
			break;
		}
	}

	CGameInstance() : GameStart(0) {}

};

#endif